package io.wongd.lib_douyin.ui

import android.os.Environment
import androidx.annotation.WorkerThread
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.lifecycleScope
import coil.compose.AsyncImage
import io.wongd.lib_douyin.Douyin
import io.wongd.lib_douyin.db.DouyinBean
import io.wongd.lib_douyin.db.requireDouyinDB
import io.wongd.lib_douyin.util.OpenPic
import io.wongd.lib_douyin.util.OpenVideo
import io.wongxd.lib_downloadx.core.DownloadConfig
import io.wongxd.lib_downloadx.core.DownloadxState
import io.wongxd.lib_downloadx.downloadx
import io.wongxd.solution.baseView.BaseComposeToolBarFgt
import io.wongxd.solution.logger.WLogUtil
import io.wongxd.solution.util.FileUtilW
import io.wongxd.solution.util.coroutine.CoroutineTaskHelper
import io.wongxd.solution.util.setDropFastClick
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import org.jsoup.Jsoup
import java.io.File
import java.net.URL
import java.util.concurrent.TimeUnit


// todo 判断文件是否存在
// todo 链接失效？失效 403 就去重新获取？
class FgtDownload : BaseComposeToolBarFgt() {
    override fun lazyInit() {
    }

    override val blackTint: Boolean
        get() = true

    override val title: String
        get() = "下载管理"

    //<editor-fold desc="工具">

    private fun getSaveDir(): String {
        return FileUtilW.getAppDownloadPath("douyinDown")
    }

    private fun getSaveDirFullPath(): String {
        val dirPath = getSaveDir()
        val dir = File(Environment.getExternalStorageDirectory(), dirPath)
        if (dir.exists().not()) dir.mkdirs()
        return dir.absolutePath
    }

    @WorkerThread
    private fun getRealDownloadUrl(url: String): String {
        val hb = Headers.Builder()
        requireDownloadHeader(url).forEach { hb.add(it.key, it.value) }

        val request = Request.Builder().get()
            .url(url)
            .headers(hb.build())
            .build()

        val client = OkHttpClient.Builder()
            .connectTimeout(10L, unit = TimeUnit.SECONDS)
            .followRedirects(false)
            .build()
        val response = client.newCall(request).execute()
        val responseCode = response.code
//        println(">>>> code ${response.code}")
        var realUrl: String = url
        //重定向后重试
        if (responseCode == 302) {/*for (header in response.headers) {
                     println(">>>> $header")
                 }*/
            response.headers["Location"]?.let {
                realUrl = it
            }
//            println(">>>> 重定向 url -> $newUrl")
        }
        return realUrl
    }

    private fun requireDownloadHeader(url: String) = mapOf(
        "Host" to URL(url).host,
        "Connection" to "keep-alive",
        "User-Agent" to Douyin.userAgent
    )

    private fun requireDownloadxConfig(url: String): DownloadConfig = DownloadConfig(customHeader = requireDownloadHeader(url))


    //</editor-fold>

    private val douyinDao by lazy { requireContext().requireDouyinDB().douyinDao() }

    private val dbList by lazy { douyinDao.loadAll() }

    private val coroutineScope = lifecycleScope

    @Composable
    override fun Render() {

        val listState = dbList.collectAsState(initial = emptyList())

        Column(
            Modifier
                .navigationBarsPadding()
                .fillMaxWidth()
        ) {

            Text(
                text = "${listState.value.size}", textAlign = TextAlign.Center,
                modifier = Modifier
                    .padding(15.dp)
                    .fillMaxWidth()
            )

            LazyColumn(content = {
                itemsIndexed(listState.value) { index, item ->
                    if (item.isVideo) {
                        RenderVideoItem(coroutineScope = coroutineScope, index = index, item = item)
                    } else {
                        RenderPicListItem(coroutineScope = coroutineScope, index = index, item = item)
                    }
                }
            })

        }
    }

    @Composable
    private fun RenderDownloadItem(coroutineScope: CoroutineScope, parentIndex: Int, title: String, cover: String, url: String, isVideo: Boolean) {

        val progressState = remember {
            mutableStateOf<DownloadxState>(DownloadxState.None())
        }

        val saveDir = remember { getSaveDirFullPath() }

        val saveName = remember { "${title}.${if (isVideo) "mp4" else "jpeg"}" }

        val task = remember {
            downloadx(url = url, saveDir = saveDir, saveName = saveName, downloadConfig = requireDownloadxConfig(url))
        }

        val progressJob = remember {
            task.state(interval = 500).onEach { progressState.value = it }.launchIn(coroutineScope)
        }

        DisposableEffect(key1 = Unit, effect = {
            onDispose {
                progressJob.cancel()
            }
        })

        Row(
            Modifier
                .padding(horizontal = 10.dp)
                .padding(top = 10.dp)
                .fillMaxWidth()
                .height(120.dp)
        ) {

            AsyncImage(model = cover, contentDescription = null, modifier = Modifier.width(65.dp))

            Column(Modifier.weight(1f), verticalArrangement = Arrangement.Center) {
                Text(text = title)

                Spacer(modifier = Modifier.height(8.dp))

                AndroidView(factory = {
                    val btn = ProgressButton(it)

                    btn.setDropFastClick {

                        when {
                            task.isSucceed() -> {
                                // 查看
                                if (isVideo) OpenVideo.open(requireContext(), task.file()) else OpenPic.open(requireContext(), task.file())
                            }

                            task.isStarted() -> {
                                task.stop()
                            }

                            task.isFailed() -> {
                                // 重新获取url
//                                if (isVideo) coroutineScope.launch {
//                                    CoroutineTaskHelper.switchIo {
//                                        douyinDao.updateVideoUrlById()
//                                    }
//                                }

                            }

                            else -> {
//                                WLogUtil.d("下载: 文件地址:${task.param.saveDir},${task.param.saveName}")
                                task.start()

//                                coroutineScope.launch(Dispatchers.IO){
//                                    val document = Jsoup.connect(url).ignoreContentType(true).maxBodySize(0).timeout(0).execute()
//                                    WLogUtil.d("下载: ${document.statusCode()},${document.statusMessage()}")
//                                }
                            }
                        }
                    }

                    btn
                }, update = {
                    it.setState(progressState.value)
                }, modifier = Modifier
                    .padding(horizontal = 10.dp)
                    .fillMaxWidth()
                )
            }

        }

    }

    @Composable
    private fun RenderVideoItem(coroutineScope: CoroutineScope, index: Int, item: DouyinBean) {
        RenderDownloadItem(coroutineScope = coroutineScope, parentIndex = index, title = item.title, cover = item.coverUrl, url = item.playApi, isVideo = true)
    }

    @Composable
    private fun RenderPicListItem(coroutineScope: CoroutineScope, index: Int, item: DouyinBean) {
        item.imageList.forEachIndexed { imgIndex, url ->
            RenderDownloadItem(coroutineScope = coroutineScope, parentIndex = index, title = "${item.title}_img$imgIndex", cover = url, url = url, isVideo = false)
        }
    }

    @Preview(showBackground = true, backgroundColor = 0xffffffff)
    @Composable
    fun RenderPreView() {

    }

}